﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace ArrowScheduleCore
{
    /// <summary>
    /// Properties specific to a weekly schedule. This is set to run every Nth week on the day(s) SUN, MON, ...
    /// </summary>
    public class ScheduleWeekly : SchedulePeriod
    {
        /// <summary>
        /// What day(s) to schedule. This is hardcoded to Sunday = 0x01 and the bit shifts left for each subsequent day. This
        /// will not change. If a locale uses a different day as day 1, it is still handled in here as Sunday, not day 1 = 0x01.
        /// </summary>
        [Flags]
        public enum DAYS
        {
            /// <summary>Run on no days.</summary>
            NONE = 0,
            /// <summary>Run on Sundays.</summary>
            SUNDAY = 0x01,
            /// <summary>Run on Mondays.</summary>
            MONDAY = 0x02,
            /// <summary>Run on Tuesdays.</summary>
            TUESDAY = 0x04,
            /// <summary>Run on Wednesdays.</summary>
            WEDNESDAY = 0x08,
            /// <summary>Run on Thursdays.</summary>
            THURSDAY = 0x10,
            /// <summary>Run on Fridays.</summary>
            FRIDAY = 0x20,
            /// <summary>Run on Saturdays.</summary>
            SATURDAY = 0x40,
            /// <summary>Run everyday.</summary>
            ALL = 0x7f
        };

        private int period;
        private DAYS days;

        /// <summary>
        /// Returns the text for the passed in day(s) of the week. 
        /// </summary>
        /// <returns>In the form "Monday, Wednesday"</returns>
        public string DaysAsString
        {
            get
            {
                DateTimeFormatInfo info = CultureInfo.CurrentUICulture.DateTimeFormat;

                // DayOfWeek goes Sunday=0 to Saturday=6
                StringBuilder buf = new StringBuilder();
                int dayOn = (int)info.FirstDayOfWeek;
                for (int num = 0; num < 7; num++)
                {
                    if (((0x01 << dayOn) & (int)days) != 0)
                    {
                        if (buf.Length > 0)
                            buf.Append(", ");
                        buf.Append(info.GetDayName((DayOfWeek)dayOn));
                    }
                    dayOn++;
                    if (dayOn > 6)
                        dayOn = 0;
                }

                return buf.ToString();
            }
        }

        /// <summary>
        /// Create a weekly schedule object.
        /// </summary>
        /// <param name="period">Schedule every N (period) weeks. This must be greater than 0.</param>
        /// <param name="days">Which days to schedule on.</param>
        public ScheduleWeekly(int period, DAYS days)
        {
            this.period = period;
            this.days = days;
        }

        /// <summary>
        /// Schedule every N (period) weeks. This must be greater than 0.
        /// </summary>
        public int Period
        {
            get { return period; }
            set { period = value; }
        }

        /// <summary>
        /// Which days to schedule on.
        /// </summary>
        public DAYS Days
        {
            get { return days; }
            set { days = value; }
        }

        /// <summary>
        /// Use this instead of class type only when necessary such as a switch statement.
        /// </summary>
        public override REPEAT RepeatType
        {
            get { return REPEAT.WEEKLY; }
        }

        /// <summary>
        /// A human readable description of the period.
        /// </summary>
        public override string Description
        {
            get
            {
                return String.Format(GlobalStrings.ScheduleWeekly_schdWeekly, period, DaysAsString);
            }
        }
    }
}
